import math
from abc import abstractmethod

import numpy as np
from shapely.geometry import Point
from shapely import affinity


# 几何模型：
#   负责碰撞检测
#   位置信息
#   后续用作渲染
class Model(object):
    def __init__(self, x=0, y=0):
        super(Model, self).__init__()
        # self.center = Point(x, y)
        self.gemo = None
        # 设当前物体与水平的角度为angle
        self.angle = 0  # 使用角度
        self.color = np.array([0, 0, 0])

    def set_color(self, color):
        """

        :type color: list or tuple 范围 0-1
        """
        self.color = np.array(color)

    def set_pos(self, pos):
        center_pt = self.get_pos()
        self._move(pos[0] - center_pt[0], pos[1] - center_pt[1])

    def set_angle(self, angle):
        """
        指定模型角度
        :param angle: 旋转角度°
        :return:
        """
        self.rotate(-self.angle)
        self.rotate(angle)

    @abstractmethod
    def move(self, distance):
        pass

    @abstractmethod
    def _move(self, xoff, yoff):
        pass

    # 旋转, 使用角度
    @abstractmethod
    def rotate(self, angle):
        pass
        # point不需要旋转
        # affinity.rotate(self.center, angle, use_radians=True)
        # self.angle += angle
        # if self.gemo:
        #     self.gemo = affinity.rotate(self.gemo, angle, use_radians=False)

    @abstractmethod
    def get_pos(self):
        pass
        # return self.center.coords[0]

    # 获取几何模型的所有坐标点
    @abstractmethod
    def get_gemo_pts(self):
        pass

    @abstractmethod
    def get_scaled_pts(self, xfact, yfact):
        pass

    @abstractmethod
    def contains(self, other):
        pass

    @abstractmethod
    def collision_with_other(self, other):
        pass
        if not other:
            # raise error?
            return False
        if self.gemo:
            if other.gemo:
                return not self.gemo.disjoint(other.gemo)
            else:
                return not self.gemo.disjoint(other.center)
        else:
            if other.gemo:
                return not self.center.disjoint(other.gemo)
            else:
                return not self.center.disjoint(other.center)
